// Copyright (c) 2025 Huawei Technologies Co., Ltd.
// openUBMC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//         http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Description: 图像消息处理

#include "PowerCtrl.hpp"

PowerCtrl::PowerCtrl(KvmClient& client) : client_(client) {
    client.RegisterSendMessageHandler(CMD_POWER_CONTROL_REQ_C, [this](const std::vector<uint8_t>& body) {
        return SendPowerCtrlReq(body);
    });

    client.RegisterRecvMessageHandler(CMD_POWER_CONTROL_RSP_S, [this](const std::vector<uint8_t>& body) {
        RecvPowerCtrlRsp(body);
    });
}
PowerCtrl::~PowerCtrl() = default;

std::pair<int, std::vector<uint8_t>> PowerCtrl::SendPowerCtrlReq(const std::vector<uint8_t>& body) {
    try {
        // 发送连接请求后，等待服务端的响应
        std::unique_lock<std::mutex> rspLock(powerControlMutex_);

        powerControlRsp_ = 0xff; // 查询前置成无效值
        PackData pack_data;
        client_.Send(pack_data.PowerControl(body));
        if (!powerControlCv_.wait_for(rspLock, std::chrono::seconds(RESPONSE_TIMEOUT),
            [this]() { return powerControlRsp_ != 0xff; })) {
                client_.LogMessage("PowerControl: Timeout waiting for response.");
            return {E_TIMEOUT, {}};
        }

        const int retCodeNoPriv = 2;
        if (powerControlRsp_ == 0) {
            return {E_OK, {powerControlRsp_}};
        } else if (powerControlRsp_ == retCodeNoPriv) {
            return {E_INSUFFICIENT_PRIVILEGE, {}};
        } else {
            return {E_ERR, {}};
        }
    } catch(const std::exception& e) {
        client_.LogMessage(std::string("Exception in SetBootOption: ") + e.what());
        return {E_ERR, {}};
    }
}

void PowerCtrl::RecvPowerCtrlRsp(const std::vector<uint8_t>& body) {
    if (body.size() != 1) {
        client_.LogMessage("PowerControl: Invalid response size.");
        powerControlRsp_ = E_ERR; // 失败设置为无效值
        return;
    }

    uint8_t rspCode = body[0];
    std::lock_guard<std::mutex> lock(powerControlMutex_);
    powerControlRsp_ = rspCode; // 根据响应码设置结果
    powerControlCv_.notify_one(); // 通知等待的线程
}
